「场景设计」聊天窗口中消息自动滚动到底部

您所在的位置:网站首页 blazor 移动端 「场景设计」聊天窗口中消息自动滚动到底部

「场景设计」聊天窗口中消息自动滚动到底部

2023-08-26 08:35| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

背景

笔者最近在参与一个客服咨询系统的开发工作,负责的是客服端的 WEB 平台,该平台面向于公司内部的客服工作人员,为客服提供和客户在线沟通的功能,目前只做了文字消息,后续会考虑加上语音、图片、视频等沟通媒介,双方的消息都放到一个列表中,再渲染到 DOM 上。

开发过程中遇到一个问题,在 DOM 文档中,消息过多使得消息列表的高度溢出父元素后,父元素产生滚动条,溢出的消息需要下拉滚动条才能看到,这非常影响用户体验。

于是,笔者开始调研聊天窗口中消息自动滚动到底部的解决方案,并确定了一种方案,实现了该功能,最后输出了本文。下面是笔者的心路历程以及方案的详细描述,掘友们如果有更好的方案,欢迎指教👏👏

实现功能

实现本功能的核心方法是 Element.scrollIntoView,同时还涉及CSS盒模型,CSS伪类,获取DOM结点 等知识。

获取最后一条消息的 DOM 结点

笔者采用 Element.querySelector 来获取 DOM 结点,因为此方法可通过 CSS选择器 的方式来使用,通过 :last-of-type 就可以轻松选到最后一个消息结点,笔者觉得很方便。

const lastMessage = document.querySelector('.message:last-of-type'); 滚动消息的父元素

父元素已设置 overflow:auto,因此当消息溢出时已经出现滚动条,此时调用消息结点的 scrollIntoView 方法,该方法滚动的是 element.parent,正好是消息结点的父元素。

Element.scrollIntoView方法接收一个参数,该参数可以对滚动过程进行定制,笔者使用Object型参数传参,执行的动画效果是 smooth 过渡,垂直方向对齐为 end,水平方向对齐为 nearest。

lastMessage.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" }); 出现问题

此时问题出现,.message 的父元素不能滚动到底部,这是因为笔者给 .message 这个盒子设置了 margin-bottom,而 Element.scrollIntoView 只会将父元素滚动到 完整出现 message 的 Border Box 区域,不包括 Margin Box 部分 (参考CSS盒模型),所以最后滚动完毕时会缺少滚动一部分 margin-bottom 的距离,看起来就是没有滚动到底。

解决问题

笔者改变了 .message 的样式,当然不影响 UI 的展示,只是把 .message 的 margin-bottom 改成了 padding-bottom。

因为在 CSS盒模型 中, Padding Box 在 Border Box 的内侧,所以当完整出现 Border Box 时,Padding Box 必然已经出现了,这样就能把 .message 盒子完整地展示出来,视觉上就是滚动到底的效果。

DEMO 聊天窗口消息自动滚动到底部 .chat { display: flex; align-items: center; justify-content: center; height: 600px; } .chat-body { height: 400px; width: fit-content; overflow: auto; border: 1px solid yellowgreen; } .message { width: 500px; height: 80px; /* margin-top: 10px; */ /* margin-bottom: 10px; */ padding-top: 10px; padding-bottom: 10px; background-color: #eee; } 滚动到底部 message1 message2 message3 message4 message5 message6 function doit() { const lastMessage = document.querySelector('.message:last-of-type'); lastMessage.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" }); } 参考

CSS盒模型 | MDN

CSS伪类:last-of-type | MDN

Element.scrollIntoView | MDN



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3